﻿using System;
using System.Collections.Generic;
using gbL.NetBoard.Broadcast;

namespace gbL.NetBoard
{
    public interface IBlackboard
    {
        /// <summary>
        /// Add an item to the blackboard
        /// </summary>
        /// <param name="message">The payload of the entry</param>
        IBlackboardEntry Add(object message);
        /// <summary>
        /// Add an item to the blackboard
        /// </summary>
        /// <param name="from">Object submitting the entry</param>
        /// <param name="message">The payload of the entry</param>
        IBlackboardEntry Add(object from, object message);
        /// <summary>
        /// Add an item to the blackboard
        /// </summary>
        /// <param name="tag">An arbitrary object which tags this entry</param>
        /// <param name="from">Object submitting the entry</param>
        /// <param name="message">The payload of the entry</param>
        IBlackboardEntry Add(object tag, object from, object message);
        /// <summary>
        /// Reads all entries from the blackboard
        /// </summary>
        /// <returns>Entries from the blackboard</returns>
        IList<IBlackboardEntry> Read(); 
        /// <summary>
        /// Return but do not remove matching entries from the blackboard
        /// </summary>
        /// <param name="selector">Func used to evaluate entries to return</param>
        /// <returns>Matching entries (or empty IList)</returns>
        IList<IBlackboardEntry> Read(Func<IBlackboardEntry, bool> selector);
        /// <summary>
        /// Return and remove matching entries from the blackboard
        /// </summary>
        /// <param name="selector">Func used to evaluate entries to return</param>
        /// <returns>Matching entries (or empty IList)</returns>
        IList<IBlackboardEntry> Take(Func<IBlackboardEntry, bool> selector);
        /// <summary>
        /// Return but do not remove entries which are tagged with this value
        /// </summary>
        /// <param name="tag">Tag to search for</param>
        /// <returns>Matching entries (or empty IList)</returns>
        IList<IBlackboardEntry> ReadWithTag(object tag);
        /// <summary>
        /// Return and remove matching entries from the blackboard
        /// </summary>
        /// <param name="tag">Tag to search for</param>
        /// <returns>Matching entries (or empty IList)</returns>
        IList<IBlackboardEntry> TakeWithTag(object tag);
        /// <summary>
        /// Return and remove matching entry from the blackboard
        /// </summary>
        /// <param name="entry">Entry to remove</param>
        /// <returns>Removed entry if found</returns>
        IBlackboardEntry TakeEntry(IBlackboardEntry entry);
        /// <summary>
        /// Broadcast object which dispatches events regarding message changes
        /// </summary>
        IFilteringBroadcaster Broadcaster { get; }

    }
}
